﻿#include "ZQtDebugLogBrowser.h"

#include <QVBoxLayout>
#include <QMenu>
#include <QScopedPointer>
#include <QTextBrowser>
#include <QToolBar>
#include <QToolButton>
#include <QAction>
#include <QLabel>
#include <QDateTime>

#define DEFAULT_MAX_LOG_COUNT_DISPLAYED 5000

ZQtDebugLogBrowser::ZQtDebugLogBrowser(QWidget *parent)
    : QMainWindow(parent),
      m_max_log_count(DEFAULT_MAX_LOG_COUNT_DISPLAYED),
      m_show_debug_msg(false)
{
    init();
}

void ZQtDebugLogBrowser::initUI()
{
    // 文本浏览器
    m_browser = new QTextBrowser;
    quint32 max_log_count_displayed = m_max_log_count;
    m_browser->document()->setMaximumBlockCount(max_log_count_displayed);

    m_toolbar = new QToolBar();
    m_action_clear = new QAction(QIcon(QStringLiteral("://image/clear.png")),
                                 tr("Clear"), this);
    m_action_debug = new QAction(QIcon(QStringLiteral("://image/bug_128.png")),
                                 tr("Show Debug"), this);
    m_action_debug->setCheckable(true);

    m_toolbar->addAction(m_action_clear);
    m_toolbar->addAction(m_action_debug);
    m_toolbar->setFixedHeight(32);

    // 显示的最大日志条数
    m_label_max_log = new QLabel(QString::number(max_log_count_displayed));
    m_toolbar->addWidget(m_label_max_log);
    addToolBar(Qt::BottomToolBarArea, m_toolbar);
    setCentralWidget(m_browser);

    m_browser->setContextMenuPolicy(Qt::CustomContextMenu);

    // 翻译
    translateLanguage();
}

void ZQtDebugLogBrowser::createConnects()
{
    connect(m_action_clear, SIGNAL(triggered(bool)), this, SLOT(slotClearBrowser()));
    connect(m_browser, SIGNAL(customContextMenuRequested(QPoint)),
            this, SLOT(slotContextMenuRequested(QPoint)));
    connect(m_action_debug, SIGNAL(toggled(bool)),
            this, SLOT(slotSetShowDebugMessageEnable(bool)));
}

void ZQtDebugLogBrowser::slotClearBrowser()
{
    clearDisplay();
}

void ZQtDebugLogBrowser::slotContextMenuRequested(const QPoint &pos)
{
    QScopedPointer<QMenu> context_menu(m_browser->createStandardContextMenu(pos));
    context_menu->addAction(m_action_clear);
    context_menu->exec(m_browser->mapToGlobal(pos));
}

ZQtDebugLogBrowser::~ZQtDebugLogBrowser()
{
}

void ZQtDebugLogBrowser::setMaximunLogCount(uint log_count)
{
    m_max_log_count = log_count;
    m_browser->document()->setMaximumBlockCount(m_max_log_count);
}

void ZQtDebugLogBrowser::setShowDebugMsg(bool show)
{
    m_show_debug_msg = show;
}

void ZQtDebugLogBrowser::clearDisplay()
{
    m_browser->clear();
}

void ZQtDebugLogBrowser::translateLanguage()
{
    m_action_clear->setText(tr("Clear"));
    m_action_debug->setText(tr("Debug mode"));
    m_label_max_log->setText(tr("Max Log Displayed: ").append(m_label_max_log->text()));
}

void ZQtDebugLogBrowser::slotAppendMessage(const QtMsgType &type, const QString &msg)
{
    QString final_string;
    QString time = QDateTime::currentDateTime().toString(QStringLiteral("yy/MM/dd hh:mm:ss"));

    switch (type)
    {
    case QtDebugMsg: // 调试信息
    {
        if (m_show_debug_msg)
        {
            final_string = QStringLiteral("[%1 DEBUG]  ").arg(time);
        }
        else
        {
            return;
        }
        break;
    }
    case QtInfoMsg: // 普通信息
    {
        m_browser->setTextColor(qRgb(0, 128, 0));
        final_string = QStringLiteral("[%1 INFO]  ").arg(time);
        break;
    }
    case QtWarningMsg: // 警告信息
    {
        m_browser->setTextColor(qRgb(255, 80, 00));
        final_string = QStringLiteral("[%1 WARN]  ").arg(time);
        break;
    }
    case QtCriticalMsg: // 十分重要的信息
    {
        m_browser->setTextColor(Qt::red);
        final_string = QStringLiteral("[%1 CRITICAL]  ").arg(time);
        break;
    }
    case QtFatalMsg: // 致命的、极其重要的信息
    {
        m_browser->setTextColor(Qt::red);
        m_browser->setFontUnderline(true);
        final_string = QStringLiteral("[%1 FATAL]  ").arg(time);
        break;
    }
    }

    final_string.append(msg);

    // 输出到浏览器
    m_browser->append(final_string);
    m_browser->moveCursor(QTextCursor::End); // 自动滚屏
}

void ZQtDebugLogBrowser::init()
{
    initUI();
    createConnects();
}

void ZQtDebugLogBrowser::slotSetShowDebugMessageEnable(bool show)
{
    setShowDebugMsg(show);
}
